#include "trap.h"

// arithmetic inst
#define ADD(rs, rt) \
    li $t0, rs; \
    li $t1, rt; \
    add $s0, $t0, $t1; 

#define ADDI(rs, imm) \
    li $t0, rs; \
    addi $s0, $t0, imm; 

#define ADDU(rs, rt) \
    li $t0, rs; \
    li $t1, rt; \
    addu $s0, $t0, $t1; 

#define ADDIU(rs, imm) \
    li $t0, rs; \
    addiu $s0, $t0, imm; 

#define SUB(rs, rt) \
    li $t0, rs; \
    li $t1, rt; \
    sub $s0, $t0, $t1; 

#define SUBU(rs, rt) \
    li $t0, rs; \
    li $t1, rt; \
    subu $s0, $t0, $t1; 

#define SLT(rs, rt) \
    li $t0, rs; \
    li $t1, rt; \
    slt $s0, $t0, $t1; 

#define SLTI(rs, imm) \
    li $t0, rs; \
    slti $s0, $t0, imm; 

#define SLTU(rs, rt) \
    li $t0, rs; \
    li $t1, rt; \
    sltu $s0, $t0, $t1; 

#define SLTIU(rs, imm) \
    li $t0, rs; \
    sltiu $s0, $t0, imm; 

#define MULT(rs, rt) \
    li $t0, rs; \
    li $t1, rt; \
    mult $t0, $t1; 

#define MULTU(rs, rt) \
    li $t0, rs; \
    li $t1, rt; \
    multu $t0, $t1; 

#define DIV(rs, rt) \
    li $t0, rs; \
    li $t1, rt; \
    div $zero, $t0, $t1;

#define DIVU(rs, rt) \
    li $t0, rs; \
    li $t1, rt; \
    divu $zero, $t0, $t1;

// logic inst
#define AND(rs, rt) \
    li $t0, rs; \
    li $t1, rt; \
    and $s0, $t0, $t1; 

#define ANDI(rs, imm) \
    li $t0, rs; \
    andi $s0, $t0, imm; 

#define LUI(imm) \
    lui $s0, imm;

#define NOR(rs, rt) \
    li $t0, rs; \
    li $t1, rt; \
    nor $s0, $t0, $t1; 

#define OR(rs, rt) \
    li $t0, rs; \
    li $t1, rt; \
    or $s0, $t0, $t1; 

#define ORI(rs, imm) \
    li $t0, rs; \
    ori $s0, $t0, imm; 

#define XOR(rs, rt) \
    li $t0, rs; \
    li $t1, rt; \
    xor $s0, $t0, $t1; 

#define XORI(rs, imm) \
    li $t0, rs; \
    xori $s0, $t0, imm; 

#define SLLV(rs, rt) \
    li $t0, rs; \
    li $t1, rt; \
    sllv $s0, $t1, $t0; 

#define SLL(rt, sa) \
    li $t0, rt; \
    sll $s0, $t0, sa; 

#define SRLV(rs, rt) \
    li $t0, rs; \
    li $t1, rt; \
    srlv $s0, $t1, $t0; 

#define SRL(rs, sa) \
    li $t0, rs; \
    srl $s0, $t0, sa; 

#define SRAV(rs, rt) \
    li $t0, rs; \
    li $t1, rt; \
    srav $s0, $t1, $t0; 

#define SRA(rt, sa) \
    li $t0, rt; \
    sra $s0, $t0, sa; 

// branch jump inst
#define BEQ(rs, rt, offset) \
    li $t0, rs; \
    nop; \
    nop; \
    li $t1, rt; \
    nop; \
    nop; \
    beq $t0, $t1, offset;

#define BNE(rs, rt, offset) \
    li $t0, rs; \
    nop; \
    nop; \
    li $t1, rt; \
    nop; \
    nop; \
    bne $t0, $t1, offset;

#define BGEZ(rs, offset) \
    li $t0, rs; \
    nop; \
    nop; \
    bgez $t0, offset;

#define BGTZ(rs, offset) \
    li $t0, rs; \
    nop; \
    nop; \
    bgtz $t0, offset;

#define BLEZ(rs, offset) \
    li $t0, rs; \
    nop; \
    nop; \
    blez $t0, offset;

#define BLTZ(rs, offset) \
    li $t0, rs; \
    nop; \
    nop; \
    bltz $t0, offset;

#define BGEZAL(rs, offset) \
    li $t0, rs; \
    nop; \
    nop; \
    bgezal $t0, offset;

#define BGEZAL(rs, offset) \
    li $t0, rs; \
    nop; \
    nop; \
    bgezal $t0, offset;

#define BLTZAL(rs, offset) \
    li $t0, rs; \
    nop; \
    nop; \
    bltzal $t0, offset;

#define J(imm) \
    j imm;

#define JAL(imm) \
    jal imm;

#define JR(rs) \
    la $t0, rs; \
    nop; \
    nop; \
    jr $t0;

#define JALR(rs) \
    la $t0, rs; \
    nop; \
    nop; \
    jalr $ra, $t0;

// datamove inst
#define MFHI() \
    mfhi $s0;

#define MFLO() \
    mflo $s0;

#define MTHI(rs) \
    li $t0, rs; \
    mthi $t0;

#define MTLO(rs) \
    li $t0, rs; \
    mtlo $t0;

// access memory inst
#define LB(base, offset) \
    li $t0, base; \
    lb $s0, offset($t0);

#define LBU(base, offset) \
    li $t0, base; \
    lbu $s0, offset($t0);

#define SB(data, base, offset) \
    li $t0, data; \
    li $t1, base; \
    sb $t0, offset($t1); \

#define LH(base, offset) \
    li $t0, base; \
    lh $s0, offset($t0);

#define LHU(base, offset) \
    li $t0, base; \
    lhu $s0, offset($t0);

#define SH(data, base, offset) \
    li $t0, data; \
    li $t1, base; \
    sh $t0, offset($t1); \

#define LW(base, offset) \
    li $t0, base; \
    lw $s0, offset($t0);

#define SW(data, base, offset) \
    li $t0, data; \
    li $t1, base; \
    sw $t0, offset($t1); 



